#include "mxsetup.h"

.section .text.entrypoint, "ax"
.global __start
.type __start, %function
__start:
    /* set the interrupt vector */
    ldr x0, =system_vectors
    msr vbar_el1, x0

    /* set the stack pointer of el1 casually (0x40080000) (before enable mmu) */
    msr spsel, #1
    adr x0, __start
    mov sp, x0

    /* clear the bss section to 0 */   /* FIXME: 8 字节对齐写入，效率较低 */
    ldr x0, =__bss_start
    ldr x1, =__bss_end
#if defined(MX_USE_MMU)
    ldr x2, =MX_KERNEL_VPOFF
    add x0, x0, x2
    add x1, x1, x2
#endif
clean_bss_start:
    cmp x0, x1
    blt clean_bss
    b clean_bss_end
clean_bss:
    str xzr, [x0], #8
    b clean_bss_start
clean_bss_end:

#if defined(MX_USE_MMU)
    /* SVMA initialization */
    ldr x0, =MX_SVMA_MS_START_PA    /* start address of svma memory space */
    ldr x1, =MX_SVMA_MS_SIZE        /* size of svma memory space */
    bl mx_svma_init

    /* enable mmu */
    ldr x30, =mmu_enabled   /* set lr */

    mrs x0, sctlr_el1
    bic x0, x0, #(3 << 3)   /* disable SA/SA0, stack alignment check */
    bic x0, x0, #(1 << 1)   /* disable A, alignment check */
    orr x0, x0, #(1 << 12)  /* enable I, instruction cache */
    orr x0, x0, #(1 << 2)   /* enable C, data cache */
    orr x0, x0, #(1 << 0)   /* enable M, mmu */
    msr sctlr_el1, x0

    dsb sy
    isb sy
    ic ialluis              /* invalidate all instruction caches in inner-shareable domain */
    dsb sy
    isb sy
    tlbi vmalle1            /* invalidate all TLB(EL1) of stage 1 with the current VMID  */
    dsb sy
    isb sy
    ret
#endif

    /* set the stack pointer of el1 (after enable mmu) */
mmu_enabled:
    msr spsel, #1
    ldr x0, =__stack_base
    mov sp, x0

    bl mxboot
    b .
